package imp

import (
	"fmt"
	"net"

	// "github.com/golang/protobuf/jsonpb"
	"bgs/grpc/client"
	grpcActivityAPIImpl "bgs/grpc/imp/activity-api"
	grpcAfterSaleAPIImpl "bgs/grpc/imp/after_sale-api"
	grpcBrandAPIImpl "bgs/grpc/imp/brand-api"
	grpcCommonAPIImpl "bgs/grpc/imp/common-api"
	grpcOrderAPIImpl "bgs/grpc/imp/order-api"
	grpcProductAPIImpl "bgs/grpc/imp/product-api"
	grpcStoreAPIImpl "bgs/grpc/imp/store-api"
	grpcSyncAPIImpl "bgs/grpc/imp/sync-api"
	grpcUserAPIImpl "bgs/grpc/imp/user-api"
	ledgerRunner "bgs/nsqp/runners/ledger"
	orderRunner "bgs/nsqp/runners/order"
	activityService "bgs/service/activity"
	afterSaleService "bgs/service/afterSale"
	brandService "bgs/service/brand"
	enforcementService "bgs/service/enforcement"
	ledgerService "bgs/service/ledger"
	orderService "bgs/service/order"
	paymentService "bgs/service/payment"
	productService "bgs/service/product"
	spokesmanService "bgs/service/spokesman"
	storeService "bgs/service/store"
	userService "bgs/service/user"
	warehouseService "bgs/service/warehouse"
	wxpMinaService "bgs/wxp/mina"
	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
	"go.uber.org/zap"
	"google.golang.org/grpc"

	// "google.golang.org/protobuf/encoding/protojson"

	"bgs/cache/redisImp"
	"bgs/component"
	"bgs/conf"
	"bgs/db"
	"bgs/grpc/gen/service/activity"
	"bgs/grpc/gen/service/activity_stat"
	"bgs/grpc/gen/service/activity_user_award"
	"bgs/grpc/gen/service/activity_user_procedure"
	"bgs/grpc/gen/service/activity_user_pv_log"
	"bgs/grpc/gen/service/after_sale"
	"bgs/grpc/gen/service/brand"
	"bgs/grpc/gen/service/brand_admin"
	"bgs/grpc/gen/service/brand_bank_card"
	"bgs/grpc/gen/service/brand_distribute_request"
	"bgs/grpc/gen/service/brand_distributor"
	"bgs/grpc/gen/service/brand_endorse_request"
	"bgs/grpc/gen/service/brand_fan"
	"bgs/grpc/gen/service/brand_follow"
	"bgs/grpc/gen/service/brand_spokesman"
	"bgs/grpc/gen/service/brand_warehouse"
	"bgs/grpc/gen/service/common"
	"bgs/grpc/gen/service/order"
	"bgs/grpc/gen/service/product"
	"bgs/grpc/gen/service/product_group"
	"bgs/grpc/gen/service/store"
	"bgs/grpc/gen/service/store_endorse_request"
	"bgs/grpc/gen/service/store_fan"
	"bgs/grpc/gen/service/store_follow"
	"bgs/grpc/gen/service/store_spokesman"
	"bgs/grpc/gen/service/sync"
	"bgs/grpc/gen/service/user"
	"bgs/grpc/gen/service/user_fan"
	"bgs/grpc/gen/service/user_follow"
	"bgs/grpc/gen/service/user_pv_log"
	"bgs/grpc/gen/service/wxpay_applyment"
	"bgs/grpc/gen/util/gsms_proxy"
	"bgs/grpc/gen/util/status"
	grpcUtil "bgs/grpc/imp/util"
	"bgs/grpc/middleware"
	"bgs/pkg/cos"
	// "bgs/qiniu"
)

var (
	grpcClientProxy *client.GrpcClientProxy
)

// InitGRPC 初始化grpc server
func InitGRPC(
	nsqConf conf.NsqSection,
	grpcConf conf.GrpcSection,
	wechatConfPtr *conf.WechatSection,
	vars *conf.VarsSection,
	pgdao *db.PgDao,
	cos *cos.Cos,
	slog *zap.SugaredLogger,
	adp *cache.Adapter,
	clientProxy *client.GrpcClientProxy,
	cm *component.ComponentManger,
) {
	slog = slog.With("entry", "grpc")
	lis, err := net.Listen("tcp", fmt.Sprintf("%s:%s", grpcConf.Host, grpcConf.Port))
	if err != nil {
		slog.Fatalf("failed to listen: %v", err)
	}
	s := grpc.NewServer(
		grpc.UnaryInterceptor(
			grpc_middleware.ChainUnaryServer(
				middleware.UnaryRequestIDInterceptor(slog),
				middleware.UnaryLoggingInterceptor(slog),
				middleware.UnaryRecoveryInterceptor(slog),
			),
		),
	)

	// grpc client proxy
	grpcClientProxy = clientProxy

	// util
	pgErrorChecker := grpcUtil.NewPgErrorChecker(slog)

	// nsqp runner
	orderRunner, err := orderRunner.NewNsqOrderRunner(nsqConf, slog)
	if err != nil {
		slog.Fatalf("failed to init orderRunner: %v", err)
		return
	}
	ledgerRunner, err := ledgerRunner.NewNsqLedgerRunner(nsqConf, slog)
	if err != nil {
		slog.Fatalf("failed to init ledgerRunner: %v", err)
		return
	}

	// biz services
	activityService := activityService.NewActivityService(pgdao, slog, wechatConfPtr, vars, clientProxy, adp, cm)
	afterSaleService := afterSaleService.NewAfterSaleService(pgdao, slog, wechatConfPtr, vars, clientProxy, adp)
	brandService := brandService.NewBrandService(pgdao, slog, wechatConfPtr, vars, clientProxy, adp)
	enforcementService := enforcementService.NewEnforcementService(pgdao, slog, wechatConfPtr, vars, clientProxy, adp)
	ledgerService := ledgerService.NewLedgerService(pgdao, slog, wechatConfPtr, vars, clientProxy, adp, ledgerRunner)
	orderService := orderService.NewOrderService(pgdao, slog, vars, clientProxy, adp, orderRunner)
	paymentService := paymentService.NewPaymentService(pgdao, slog, wechatConfPtr, vars, clientProxy, adp)
	productService := productService.NewProductService(pgdao, slog, vars, clientProxy, adp)
	storeService := storeService.New(pgdao, slog, wechatConfPtr, vars, clientProxy, adp)
	spokesmanService := spokesmanService.NewSpokesmanServiceImp(pgdao, slog, vars, clientProxy, adp)
	userService := userService.NewUserService(pgdao, slog, wechatConfPtr, vars, clientProxy, adp)
	warehouseService := warehouseService.NewWarehouseService(pgdao, slog, vars, clientProxy, adp)
	wxpMinaService := wxpMinaService.NewMinaService(pgdao, slog, wechatConfPtr, vars, adp)

	// grpc router

	// util
	utilService := NewUtilService(pgdao.Q, slog)
	gsms_proxy.RegisterGsmsProxyOpServer(s, utilService)
	status.RegisterStatusOpServer(s, utilService)

	// 第三方相关服务
	thirdSrv := NewWechatService(wechatConfPtr, cos, slog)
	thirdSrv.RegisterService(s)

	// 星团业务服务
	activityAPIService := grpcActivityAPIImpl.NewActivityAPIService(pgdao, slog, vars, grpcClientProxy, adp, activityService, brandService, productService, spokesmanService, storeService, userService)
	activity.RegisterActivityOpServer(s, activityAPIService)
	activity_stat.RegisterActivityStatOpServer(s, activityAPIService)
	activity_user_award.RegisterActivityUserAwardOpServer(s, activityAPIService)
	activity_user_procedure.RegisterActivityUserProcedureOpServer(s, activityAPIService)
	activity_user_pv_log.RegisterActivityUserPvLogOpServer(s, activityAPIService)

	afterSaleAPIService := grpcAfterSaleAPIImpl.NewAfterSaleAPIService(pgdao, slog, vars, grpcClientProxy, adp, afterSaleService, ledgerService, orderService, paymentService, wxpMinaService)
	after_sale.RegisterAfterSaleOpServer(s, afterSaleAPIService)

	brandAPIService := grpcBrandAPIImpl.NewBrandAPIService(pgdao, slog, vars, grpcClientProxy, adp, activityService, brandService, productService, spokesmanService, userService, warehouseService, wxpMinaService)
	brand.RegisterBrandOpServer(s, brandAPIService)
	brand_admin.RegisterBrandAdminOpServer(s, brandAPIService)
	brand_fan.RegisterBrandFanOpServer(s, brandAPIService)
	brand_follow.RegisterBrandFollowOpServer(s, brandAPIService)
	brand_bank_card.RegisterBrandBankCardOpServer(s, brandAPIService)
	brand_distributor.RegisterBrandDistributorOpServer(s, brandAPIService)
	brand_distribute_request.RegisterBrandDistributeRequestOpServer(s, brandAPIService)
	brand_endorse_request.RegisterBrandEndorseRequestOpServer(s, brandAPIService)
	brand_spokesman.RegisterBrandSpokesmanOpServer(s, brandAPIService)
	brand_warehouse.RegisterBrandWarehouseOpServer(s, brandAPIService)
	wxpay_applyment.RegisterWxpayApplymentOpServer(s, brandAPIService)

	commonAPIService := grpcCommonAPIImpl.NewCommonAPIService(pgdao, slog, vars, grpcClientProxy, adp, warehouseService)
	common.RegisterCommonOpServer(s, commonAPIService)

	orderAPIService := grpcOrderAPIImpl.NewOrderAPIService(pgdao, slog, vars, grpcClientProxy, adp, activityService, brandService, enforcementService, orderService, paymentService, storeService, userService)
	order.RegisterOrderOpServer(s, orderAPIService)

	productAPIService := grpcProductAPIImpl.NewProductAPIService(pgdao, slog, productService)
	product.RegisterProductOpServer(s, productAPIService)
	product_group.RegisterProductGroupOpServer(s, productAPIService)

	storeAPIService := grpcStoreAPIImpl.New(pgdao, slog, vars, grpcClientProxy, adp, activityService, brandService, productService, spokesmanService, storeService, userService, wxpMinaService)
	store.RegisterStoreOpServer(s, storeAPIService)
	store_fan.RegisterStoreFanOpServer(s, storeAPIService)
	store_follow.RegisterStoreFollowOpServer(s, storeAPIService)
	store_endorse_request.RegisterStoreEndorseRequestOpServer(s, storeAPIService)
	store_spokesman.RegisterStoreSpokesmanOpServer(s, storeAPIService)

	syncAPIService := grpcSyncAPIImpl.NewSyncAPIService(pgdao, slog)
	sync.RegisterSyncOpServer(s, syncAPIService)

	userAPIService := grpcUserAPIImpl.NewUserAPIService(pgdao, slog, vars, grpcClientProxy, adp, pgErrorChecker, userService)
	user.RegisterUserOpServer(s, userAPIService)
	user_fan.RegisterUserFanOpServer(s, userAPIService)
	user_follow.RegisterUserFollowOpServer(s, userAPIService)
	user_pv_log.RegisterUserPvLogOpServer(s, userAPIService)

	slog.Info("grpc started")
	if err := s.Serve(lis); err != nil {
		slog.Fatalf("failed to serve: %v", err)
	}
}
